package cn.bugstack.ai.service;

import cn.bugstack.ai.model.TraceRecord;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.Map;

import static org.junit.jupiter.api.Assertions.*;

/**
 * TracingService 单元测试
 * 
 * @author bugstack
 */
class TracingServiceTest {
    
    private TracingService tracingService;
    
    @BeforeEach
    void setUp() {
        tracingService = new TracingService();
    }
    
    @Test
    void testCreateTraceId() {
        String traceId = tracingService.createTraceId();
        assertNotNull(traceId);
        assertTrue(traceId.startsWith("trace_"));
        assertTrue(traceId.length() > 20);
    }
    
    @Test
    void testRecordStep() {
        String traceId = tracingService.createTraceId();
        tracingService.recordStep(traceId, 1, "test_action", 
                "Test Description", "input", "output");
        
        List<TraceRecord> records = tracingService.getTraceRecords(traceId);
        assertEquals(1, records.size());
        
        TraceRecord record = records.get(0);
        assertEquals(traceId, record.getTraceId());
        assertEquals(1, record.getStepId());
        assertEquals("test_action", record.getAction());
        assertEquals("Test Description", record.getDescription());
    }
    
    @Test
    void testMultipleSteps() {
        String traceId = tracingService.createTraceId();
        tracingService.recordStep(traceId, 1, "step1", "Step 1", "in1", "out1");
        tracingService.recordStep(traceId, 2, "step2", "Step 2", "in2", "out2");
        tracingService.recordStep(traceId, 3, "step3", "Step 3", "in3", "out3");
        
        List<TraceRecord> records = tracingService.getTraceRecords(traceId);
        assertEquals(3, records.size());
        
        for (int i = 0; i < 3; i++) {
            assertEquals(i + 1, records.get(i).getStepId());
        }
    }
    
    @Test
    void testGetStep() {
        String traceId = tracingService.createTraceId();
        tracingService.recordStep(traceId, 1, "step1", "Step 1", "in1", "out1");
        tracingService.recordStep(traceId, 2, "step2", "Step 2", "in2", "out2");
        
        TraceRecord step1 = tracingService.getStep(traceId, 1);
        assertNotNull(step1);
        assertEquals("step1", step1.getAction());
        
        TraceRecord step2 = tracingService.getStep(traceId, 2);
        assertNotNull(step2);
        assertEquals("step2", step2.getAction());
    }
    
    @Test
    void testHasTrace() {
        String traceId = tracingService.createTraceId();
        assertFalse(tracingService.hasTrace(traceId));
        
        tracingService.recordStep(traceId, 1, "step1", "Step 1", "in1", "out1");
        assertTrue(tracingService.hasTrace(traceId));
    }
    
    @Test
    void testGetStepCount() {
        String traceId = tracingService.createTraceId();
        assertEquals(0, tracingService.getStepCount(traceId));
        
        tracingService.recordStep(traceId, 1, "step1", "Step 1", "in1", "out1");
        assertEquals(1, tracingService.getStepCount(traceId));
        
        tracingService.recordStep(traceId, 2, "step2", "Step 2", "in2", "out2");
        assertEquals(2, tracingService.getStepCount(traceId));
    }
    
    @Test
    void testClearTrace() {
        String traceId = tracingService.createTraceId();
        tracingService.recordStep(traceId, 1, "step1", "Step 1", "in1", "out1");
        
        assertTrue(tracingService.hasTrace(traceId));
        tracingService.clearTrace(traceId);
        assertFalse(tracingService.hasTrace(traceId));
    }
    
    @Test
    void testGetTraceSummary() {
        String traceId = tracingService.createTraceId();
        tracingService.recordStep(traceId, 1, "step1", "Step 1", "in1", "out1", 100L);
        tracingService.recordStep(traceId, 2, "step2", "Step 2", "in2", "out2", 200L);
        
        Map<String, Object> summary = tracingService.getTraceSummary(traceId);
        assertNotNull(summary);
        assertEquals(traceId, summary.get("traceId"));
        assertEquals(2, summary.get("totalSteps"));
        assertEquals(300L, summary.get("totalDuration"));
    }
}
